<template>
  <el-card class="wrapper">
    <el-form inline>
      <el-form-item>
        <el-input v-model="paramsState.username" placeholder="用户名" />
      </el-form-item>

      <el-form-item class="ml-10">
        <el-button
          type="primary"
          icon="el-icon-search"
          size="middle"
          @click="search"
          >查询</el-button
        >
        <el-button type="default" size="middle" @click="resetSearch"
          >清空</el-button
        >
      </el-form-item>
    </el-form>

    <div style="margin: 20px 0">
      <el-button
        type="primary"
        size="small"
        @click="userState.dialogUserVisible = true"
        >添 加</el-button
      >
      <el-button
        type="danger"
        size="small"
        :disabled="tableState.selectedIds.length === 0"
        @click="removeUsers"
        >批量删除</el-button
      >
    </div>

    <el-table
      :data="tableState.users"
      v-loading="listLoading"
      @selection-change="handleSelectionChange"
      border
      stripe
    >
      <el-table-column type="selection" width="55" />

      <el-table-column type="index" label="序号" width="80" align="center" />

      <el-table-column prop="username" label="用户名" width="150" />
      <el-table-column prop="nickName" label="用户昵称" />
      <el-table-column prop="roleName" label="角色列表" width="200" />
      <el-table-column prop="gmtCreate" label="创建时间" width="180" />
      <el-table-column prop="gmtModified" label="更新时间" width="180" />

      <el-table-column label="操作" width="200" align="center" fixed="right">
        <template v-slot="{ row }">
          <el-button
            type="info"
            size="small"
            icon="el-icon-s-custom"
            title="分配角色"
            @click="showAssignRole(row)"
          />
          <el-button
            type="primary"
            size="small"
            icon="el-icon-edit-outline"
            title="修改用户"
            @click="showUpdateUser(row)"
          />
          <el-popconfirm
            :title="`确定删除 ${row.username} 吗?`"
            @onConfirm="removeUser(row.id)"
          >
            <template #reference>
              <el-button
                style="margin-left: 10px"
                type="danger"
                size="small"
                icon="el-icon-delete"
                title="删除用户"
              />
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <el-pagination
      :current-page="paramsState.page"
      :page-size="paramsState.limit"
      :total="tableState.total"
      :page-sizes="[5, 10, 20, 30]"
      style="padding: 20px 0"
      layout="prev, pager, next, jumper, ->, sizes, total"
      @current-change="getUserListData"
      @size-change="getUserListData(1, $event)"
    />

    <!-- 添加与编辑的弹窗 -->
    <el-dialog
      :visible.sync="userState.dialogUserVisible"
      :title="userState.user.id ? '修改用户' : '添加用户'"
      :before-close="cancel"
    >
      <el-form
        ref="userFormRef"
        :model="userState.user"
        :rules="userRules"
        label-width="120px"
      >
        <el-form-item label="用户名" prop="username">
          <el-input v-model="userState.user.username" />
        </el-form-item>
        <el-form-item label="用户昵称">
          <el-input v-model="userState.user.nickName" />
        </el-form-item>
        <el-form-item
          v-if="!userState.user.id"
          label="用户密码"
          prop="password"
        >
          <el-input v-model="userState.user.password" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="cancel">取 消</el-button>
          <el-button
            @click="addOrUpdate"
            :loading="userState.userLoading"
            type="primary"
            >确 定</el-button
          >
        </div>
      </template>
    </el-dialog>

    <!-- 分配角色的弹窗 -->
    <el-dialog
      title="设置角色"
      :visible.sync="roleState.dialogRoleVisible"
      :before-close="resetRoleData"
    >
      <el-form label-width="80px">
        <el-form-item label="用户名">
          <el-input disabled :value="userState.user.username"></el-input>
        </el-form-item>

        <el-form-item label="角色列表">
          <!-- 
            v-model 布尔值,控制选中和不选中状态
            indeterminate 布尔值,为true的时候是半选状态
          -->
          <el-checkbox
            :indeterminate="roleState.isIndeterminate"
            v-model="roleState.checkAll"
            @change="handleCheckAllChange"
            >全选</el-checkbox
          >
          <div style="margin: 15px 0"></div>
          <el-checkbox-group v-model="roleState.userRoleIds">
            <el-checkbox
              v-for="role in roleState.allRoles"
              :key="role.id"
              :label="role.id"
              @change="handleCheckedChange"
              >{{ role.roleName }}</el-checkbox
            >
          </el-checkbox-group>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button
          :loading="roleState.roleLoading"
          type="primary"
          @click="assignRole"
          >保存</el-button
        >
        <el-button @click="resetRoleData">取消</el-button>
      </template>
    </el-dialog>
  </el-card>
</template>

<script>
import aclUserApi from "@/api/aclUser";
export default {
  name: "index",
  data() {
    return {
      // 加载
      listLoading: false,
      // 搜索用户相关
      paramsState: {
        username: "",
        searchUsername: "",
        page: 1, // 当前页码
        limit: 5, // 每页数量
      },
      // 用户列表相关
      tableState: {
        total: 0, // 用户的总个数
        users: [],
        selectedIds: [],
      },
      // 添加用户相关
      userState: {
        dialogUserVisible: false,
        userLoading: false,
        user: {
          username: "",
          nickName: "",
          password: "",
        },
      },
      // 用户添加/修改表单的校验规则
      userRules: {
        username: [
          { required: true, message: "用户名必须输入" },
          { min: 4, message: "用户名不能小于4位" },
        ],
        password: [{ required: true, validator: this.validatePassword }],
      },
      // 用户角色数据
      roleState: {
        dialogRoleVisible: false,
        allRoles: [],
        userRoleIds: [],
        isIndeterminate: false,
        checkAll: false,
      },
    };
  },
  methods: {
    // 获取用户列表数据
    async getUserListData(
      page = this.paramsState.page,
      limit = this.paramsState.limit
    ) {
      this.paramsState.page = page;
      this.paramsState.limit = limit;
      this.listLoading = true;
      try {
        let result = await aclUserApi.getUserList(page, limit, {
          username: this.paramsState.searchUsername,
        });
        // console.log("用户列表", result);
        this.tableState.total = result.data.total;
        this.tableState.users = result.data.items;
        this.tableState.selectedIds = [];
      } catch (error) {
        this.$message.error("获取用户列表失败，请重试");
      }
      this.listLoading = false;
    },

    // 根据用户输入进行查询
    search() {
      this.paramsState.searchUsername = this.paramsState.username;
      this.getUserListData(1);
    },

    // 重置输入后搜索
    resetSearch() {
      this.paramsState.searchUsername = "";
      this.paramsState.username = "";
      this.getUserListData(1);
    },

    // 自定义密码校验
    validatePassword(rule, value, callback) {
      if (!value) {
        callback("密码必须输入");
      } else if (!value || value.length < 6) {
        callback("密码不能小于6位");
      } else {
        callback();
      }
    },

    // 保存的回调
    async addOrUpdate() {
      await this.$refs.userFormRef.validate();
      const { user } = this.userState;
      if (user.username === "admin") {
        alert("admin账号不能添加或更新");
        return;
      }
      this.userState.userLoading = true;
      try {
        let result = await aclUserApi.saveOrUpdateUser(user);
        console.log("保存的数据", result);
        this.userState.userLoading = false;
        this.$message.success("保存成功");
        this.getUserListData(user.id ? this.paramsState.page : 1);
        this.userState.user = {
          username: "",
          nickName: "",
          password: "",
        };
        this.userState.dialogUserVisible = false;
      } catch (error) {
        this.$message.error("保存失败，请重试");
      }
    },

    // 点击编辑的回调
    showUpdateUser(user) {
      this.userState.user = { ...user };
      this.userState.dialogUserVisible = true;
    },

    // 取消用户的保存或更新
    cancel() {
      this.userState.dialogUserVisible = false;
      this.userState.user = {
        username: "",
        nickName: "",
        password: "",
      };
    },

    // 删除某个用户的回调
    async removeUser(id) {
      await aclUserApi.removeOneUser(id);
      this.$message.success("删除成功");
      this.getUserListData(
        this.tableState.users.length === 1
          ? this.paramsState.page - 1
          : this.paramsState.page
      );
    },

    // 列表选中状态发生改变的监听回调
    handleSelectionChange(selection) {
      // console.log('选中状态改变时',selection.map(item => item.id));
      this.tableState.selectedIds = selection.map((item) => item.id);
      // console.log('收集到的选中数据',this.tableState.selectedIds);
    },

    // 删除所有选中的用户
    removeUsers() {
      this.$confirm(`确认删除这些品牌么?`, "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      })
        //#region
        // 接口原因这个暂时不可用
        /* .then(async () => {
          try {
            // 此处由于接口必能使用，所以在删除的时候循环遍历一条一条的删除
            // await aclUserApi.removeSomeUsersApi(
            //   this.tableState.selectedIds
            // );
            // console.log("删除的数据", result);
            this.$message({
              type: "success",
              message: "删除成功!",
            });
            this.getUserListData();
          } catch (error) {
            console.log("删除失败的错误", error);
            this.$message.error("删除失败，请重试");
          }
        }) */
        //#endregion
        .then(async () => {
          try {
            this.tableState.selectedIds.forEach(async (item) => {
              await aclUserApi.removeOneUser(item);
              this.getUserListData();
            });
            this.$message({
              type: "success",
              message: "批量删除成功!",
            });
          } catch (error) {
            this.$message.error("批量删除删除失败，请重试");
          }
          // this.tableState.selectedIds.forEach(async (item) => {
          //   try {
          //     await aclUserApi.removeOneUser(item);
          //     this.$message({
          //       type: "success",
          //       message: "删除成功!",
          //     });
          //     this.getUserListData();
          //   } catch (error) {
          //     this.$message.error("删除失败，请重试");
          //   }
          // });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消删除",
          });
        });
    },

    // 显示指定角色界面
    showAssignRole(user) {
      this.userState.user = user;
      this.roleState.dialogRoleVisible = true;
      // 调用获取角色列表的函数
      this.getRoles();
    },

    // 获取角色列表
    async getRoles() {
      try {
        let result = await aclUserApi.getUserRoleList(this.userState.user.id);
        console.log("角色数据", result);
        const { allRolesList, assignRoles } = result.data;
        this.roleState.allRoles = allRolesList;
        this.roleState.userRoleIds = assignRoles.map((item) => item.id);

        this.roleState.checkAll = allRolesList.length === assignRoles.length;
        this.roleState.isIndeterminate =
          assignRoles.length > 0 && assignRoles.length < allRolesList.length;
      } catch (error) {}
    },

    // 全选勾选状态发生改变
    handleCheckAllChange(value) {
      // 如果当前全选, userRoleIds就是所有角色id的数组, 否则是空数组
      this.roleState.userRoleIds = value
        ? this.roleState.allRoles.map((item) => item.id)
        : [];
      // 如果当前不是全选也不全不选时, 指定为false
      this.roleState.isIndeterminate = false;
    },

    // 角色列表选中项发生改变的监听
    handleCheckedChange() {
      const { userRoleIds, allRoles } = this.roleState;
      this.roleState.checkAll = userRoleIds.length === allRoles.length;
      this.roleState.isIndeterminate =
        userRoleIds.length > 0 && userRoleIds.length < allRoles.length;
    },

    // 为用户分配角色，即保存
    async assignRole() {
      try {
        // 暂存用户id,和角色的id
        const userId = this.userState.user.id;
        const roleIds = this.roleState.userRoleIds.join(",");
        this.roleState.roleLoading = true;
        await aclUserApi.assignUserRoleList(userId, roleIds);
        this.roleState.roleLoading = false;
        this.$message.success("分配角色成功");
        // 重置信息
        this.resetRoleData();
        this.getUserListData();
      } catch (error) {
        this.$message.error("分配用户角色失败，请重试");
      }
    },
    // 重置用户角色的数据
    resetRoleData() {
      Object.assign(this.roleState, {
        dialogRoleVisible: false,
        allRoles: [],
        userRoleIds: [],
        isIndeterminate: false,
        checkAll: false,
      });
    },
  },
  mounted() {
    this.getUserListData();
  },
};
</script>

<style scoped>
.wrapper {
  margin: 20px;
  width: 96%;
}
</style>